package com.project.class8_17.dao.impl;

import com.project.class8_17.bean.annotation.Column;
import com.project.class8_17.bean.annotation.Id;
import com.project.class8_17.bean.annotation.Table;

import java.lang.reflect.Field;
import java.sql.*;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

public class BaseDao {
    protected Connection con;
    protected PreparedStatement ps;
    protected ResultSet rs;

    public void setConnection(){
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            con = DriverManager.getConnection("jdbc:mysql://localhost:12345/mydb?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false"
                    ,"root","lovo");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void closeConnection(){
        try {
            if(rs != null) {
                rs.close();
            }
            if(ps != null) {
                ps.close();
            }
            if(con != null) {
                con.close();
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

    public void insert(Object beanObj){
        this.setConnection();
        String sql = "insert into ";
        String str = "";
        //得到实体类的类模版
        Class beanClass = beanObj.getClass();
        //得到表名
        if(beanClass.isAnnotationPresent(Table.class)){
            Table table = (Table)beanClass.getAnnotation(Table.class);
            sql += table.value()+"(";
        }
        try {
            //值集合
            List valueList = new ArrayList();

            //得到该类中属性列表
            Field[] fs = beanClass.getDeclaredFields();
            for (Field f : fs) {
                if (f.isAnnotationPresent(Column.class) &&
                        f.isAnnotationPresent(Id.class) == false) {//属性有column注解，没有id注解
                    //取出column注解内容
                    Column column = f.getAnnotation(Column.class);
                    sql += column.value() + ",";
                    str += "?,";

                    //去掉修饰符检查
                    f.setAccessible(true);
                    //得到实体对象的属性值
                    Object value = f.get(beanObj);
                    valueList.add(value);
                }
            }
            sql = sql.substring(0, sql.length() - 1) + ") values(";
            str = str.substring(0,str.length() - 1) + ")";

            ps = con.prepareStatement(sql + str);
            for(int i=0;i<valueList.size();i++){
                ps.setObject(i+1,valueList.get(i));
            }

            ps.executeUpdate();
        } catch (Exception throwables) {
            throwables.printStackTrace();
        }finally{
            this.closeConnection();
        }
    }

    public List find(String sql,Class beanClass,Object... valueArray){
        List list = new ArrayList();
        this.setConnection();

        try {
            ps = con.prepareStatement(sql);
            for(int i=0;i<valueArray.length;i++){
                ps.setObject(i+1,valueArray[i]);
            }

            rs = ps.executeQuery();
            ResultSetMetaData rm = rs.getMetaData();
            int columnNum = rm.getColumnCount();

            while(rs.next()){
                Object beanObj = beanClass.getConstructor().newInstance();

                for(int i=1;i<=columnNum;i++){
                    //得到列名
                    String columnName = rm.getColumnName(i);
                    //从结果集中，得到指定列的值
                    Object value = rs.getObject(columnName);
                    if(value instanceof java.sql.Date){
                        value = LocalDate.parse(value.toString());
                    }

                    //根据列名，得到对应的属性对象
                    Field f = getField(columnName,beanClass);
                    f.setAccessible(true);
                    f.set(beanObj,value);
                }
                list.add(beanObj);
            }

        } catch (Exception throwables) {
            throwables.printStackTrace();
        }finally{
            this.closeConnection();
        }


        return list;
    }

    private Field getField(String columnName, Class beanClass) {
        Field[] fs = beanClass.getDeclaredFields();
        for(Field f : fs){
            if(f.isAnnotationPresent(Column.class)){
                Column column = f.getAnnotation(Column.class);
                if(columnName.equals(column.value())){
                    return f;
                }
            }
        }

        return null;
    }


}
